package com.topisv.tms.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springside.modules.persistence.DynamicSpecifications;
import org.springside.modules.persistence.SearchFilter;
import org.springside.modules.persistence.SearchFilter.Operator;

import com.topisv.tms.entity.Area;
import com.topisv.tms.entity.AreaGroup;
import com.topisv.tms.entity.EdiOrder;
import com.topisv.tms.repository.AreaDao;

//Spring Bean的标识.
@Component
// 默认将类中的所有public函数纳入事务管理.
@Transactional(readOnly = true)
public class AreaService {

	private AreaDao areaDao;
	protected Logger log = LoggerFactory.getLogger(getClass());
	public List<Area> findByAreaTypeAndArea(String areaType,Area area){
		return areaDao.findByAreaTypeAndArea(areaType, area);
	}
	
	public List<Area> findByAreaTypeAndArea(String[] areaTypes,Area area){
		List<Area> areas=new ArrayList<Area>();
		List<Area> tempAreas=findByAreaTypeAndArea(areaTypes[0], area);
		areas.addAll(tempAreas);
		if(areaTypes.length==2){
			areas.addAll(findByAreaTypeAndArea(areaTypes[1], area));
			for(Area a:tempAreas){
				areas.addAll(findByAreaTypeAndArea(areaTypes[1], a));
			}
		}
		
		return areas;
	}
	
	public List<Area> findByAreaType(String areaType){
		return areaDao.findByAreaType(areaType);
	}

	/**
	 * 根据省名称匹配省编码
	 * 
	 * @param filterParams
	 * @return
	 * @throws Exception
	 */
	public List<Area> getTopAreas(String areaName, String areaType)
			throws Exception {
		try {
			Specification<Area> ar = buildSpecification(areaName, areaType);
			return areaDao.findAll(ar);
		} catch (Exception e) {
			throw e;
		}
	}

	/**
	 * 根据省名称匹配省编码
	 * 
	 * @param filterParams
	 * @return
	 * @throws Exception 
	 */
	public Area getTopArea(String areaName, String areaType) throws Exception {
		try {
			List<Area> s = getTopAreas(areaName, areaType);
			if (s == null || s.isEmpty()) {
				return null;
			}
			return s.get(0);
		} catch (Exception e) {
			throw e;
		}
	}

	public Area getTopAreaBy(String provna,String cityna) {
		try {
			Area area = getTopArea(provna, "2");
			if (area == null) {
				area = getTopArea(cityna, "3");
				if (area != null) {
					area = area.getArea();
				}
			}
			return area;
		} catch (Exception e) {
			log.error("getTopAreaBy error.", e);
		}
		return null;
	}
	/**
	 * 创建动态查询条件组合.
	 */
	private Specification<Area> buildSpecification(String areaName,
			String areaType) {
		Map<String, Object> filterParams = new HashMap<String, Object>();
		filterParams.put("LIKE_areaName", areaName);
		filterParams.put("EQ_areaType", areaType);
		Map<String, SearchFilter> filters = SearchFilter.parse(filterParams);
		Specification<Area> ar = DynamicSpecifications.bySearchFilter(filters.values(), Area.class);
		return ar;
	}

	public Area getArea(Long id) {
		return areaDao.findOne(id);
	}

	@Transactional(readOnly = false)
	public List<Area> findProvoce() {
		return areaDao.findProvoce();
	}

	public Area findByAreaCode(String areaCode) {
		return areaDao.findByAreaCode(areaCode);
	}

	public Area findByAreaName(String areaName) {
		return areaDao.findByAreaName(areaName);
	}
	
	public Area findByAreaName2(String areaName) {
		return areaDao.findByAreaName2(areaName);
	}
	
	
	public Area findByAreaNameAndParentId(String areaName,Long parentId) {
		return areaDao.findByAreaNameAndParentId( areaName, parentId);
	}

	@Transactional(readOnly = false)
	public void saveArea(Area entity) {
		areaDao.save(entity);
	}

	@Transactional(readOnly = false)
	public void deleteArea(Long id) {
		areaDao.delete(id);
	}

	public List<Area> getAllArea() {
		return (List<Area>) areaDao.findAll();
	}

	public List<Map> getParentAreaTree() {
		List<Map> treeMap = new ArrayList<Map>();
		List<Area> areas = (List<Area>) areaDao.findParents();
		String split = "";
		generateTree(split, 1L, areas, treeMap);
		return treeMap;
	}

	public List<Map> getAreaTree() {
		List<Map> treeMap = new ArrayList<Map>();
		List<Area> areas = (List<Area>) areaDao.findByStatus("1");
		String split = "";
		generateTree(split, 1L, areas, treeMap);
		return treeMap;
	}

	public void generateTree(String split, Long rootid, List<Area> areas,
			List<Map> treeMap) {
		List<Area> areasTmp = new ArrayList<Area>();
		for (Area area : areas) {
			if (area.getArea().getId().intValue() == rootid) {
				areasTmp.add(area);
			}
		}
		if (areasTmp.size() == 0) {
			return;
		}
		if (rootid != 1)
			split += "&nbsp;&nbsp;&nbsp;&nbsp;";
		for (Area area2 : areasTmp) {
			HashMap map = new HashMap();
			map.put(area2.getId(), split + area2.getAreaName());
			treeMap.add(map);
			generateTree(split, area2.getId(), areas, treeMap);
		}
	}

	/**
	 * 分页显示表内所有行.
	 */
	public Page<Area> getArea(String status, Map<String, Object> filterParams,
			int pageNumber, int pageSize, String sortType) {
		PageRequest pageRequest = buildPageRequest(pageNumber, pageSize,
				sortType);
		Specification<Area> ar = buildSpecification(status, filterParams);
		return areaDao.findAll(ar, pageRequest);
	}

	/**
	 * 创建分页请求.
	 */
	private PageRequest buildPageRequest(int pageNumber, int pageSize,
			String sortType) {
		Sort sort = null;
		if (null != sortType) {
			String[] sorts = sortType.split("_");
			if (sortType.endsWith("asc")) {
				sort = new Sort(Direction.ASC, sorts[0]);
			} else if (sortType.endsWith("desc")) {
				sort = new Sort(Direction.DESC, sorts[0]);
			}
		}
		return new PageRequest(pageNumber - 1, pageSize, sort);
	}

	/**
	 * 创建动态查询条件组合.
	 */
	private Specification<Area> buildSpecification(String status,
			Map<String, Object> filterParams) {
		Map<String, SearchFilter> filters = SearchFilter.parse(filterParams);
		filters.put("status", new SearchFilter("status", Operator.EQ, status));
		Specification<Area> ar = DynamicSpecifications.bySearchFilter(
				filters.values(), Area.class);
		return ar;
	}

	@Autowired
	public void setAreaDao(AreaDao areaDao) {
		this.areaDao = areaDao;
	}

	public List<Area> getSubAreasById(Long id) {
		return areaDao.getSubAreasById(id);
	}

	public List<Area> getByAreaGroupId(Long id) {
		return areaDao.getByAreaGroupId(id);
	}

	public Area getAreaByCode(String areaCode) {
		return areaDao.findByAreaCode(areaCode);
	}

	@Transactional(readOnly = false)
	public void updateAreaGroup(AreaGroup areaGroup, long areaGroupId) {
		areaDao.updateAreaGroup(areaGroup, areaGroupId);
	}

	@Transactional(readOnly = false)
	public void updateAreaGroupByParentId(AreaGroup areaGroup, long parentId) {
		areaDao.updateAreaGroupByParentId(areaGroup, parentId);
	}

	@Transactional(readOnly = false)
	public void updateAreaGroupByGrandParentId(AreaGroup areaGroup,
			long grandParentId) {
		areaDao.updateAreaGroupByGrandParentId(areaGroup, grandParentId);
	}
}